#pragma once
#include "VisioCommon.h"
#include "GLProgram.h"
#include "texture.h"
#include "math_3d.h"
#include <opencv2\opencv.hpp>
#include <map>
#include <string>

struct SBoundingBox;

#define NUM_INDICES_IN_QUAD 6

enum ShaderType
{
	VS,
	FS
};

enum GLVarType
{
	UNIFORM,
	ATTRIB
};

typedef std::map<std::string, GLuint> ShaderVars;

struct Vertex
{
	Vertex() {}
	Vertex(Vector3f _pos, Vector3f _Tex) : position(_pos), texCoord(_Tex) {}
	Vector3f position;
	
	Vector3f texCoord;
	float bStreched;
	
	
};


struct SGLMethod
{
	CGLProgram* pProgram;
	ShaderVars vsVars;
	ShaderVars psVars;

	template<ShaderType shader, GLVarType var>
	void MapShaderVar(char* varName);
};



class CMesh
{
	void virtual v() {};
protected:
	GLuint* m_VBO;
};

class CCameraMesh : public CMesh
{
	friend class CCameraMeshInstance;
public:
	CCameraMesh();
	~CCameraMesh();
	CCameraMeshInstance* CreateInstance( Matrix4f Rotate, Matrix4f Translate, cv::Mat Image, float f );
	void InitVertices();
	SBoundingBox GetBoundingBox() const;

private:
	GLuint* m_IBO;
	Vertex* m_pVertices;
	UINT* m_pIndices;
	UINT m_NumVertices;
	UINT m_NumIndices;
	SGLMethod m_GLMethod;
	SGLMethod m_GLPicking;
	
};

class CPointOfInterest : public CMesh
{
	friend class CPointOfInterestMeshInstance;
public:
	CPointOfInterest(Vector3f FocusPoint);
	void Draw(Matrix4f WVP, Vector3f FocusPoint);
private:
	Vector3f m_FocusPoint;
	SGLMethod m_GLMethod;
	Vertex* m_pVertex;
};

class CPointCloudMesh : public CMesh
{
	friend class CPointCloudMeshInstance;
public:
	CPointCloudMesh(double* points, float* colors, UINT nVertices);
	CPointCloudMeshInstance* CreateInstance();
	SBoundingBox GetBoundingBox() const;
private:
	Vertex* m_pVertices;
	UINT m_NumVertices;
	SGLMethod m_GLMethod;
};

class CQuadMesh : public CMesh
{
	friend class CQuadMeshInstance;
public:
	CQuadMesh();
	~CQuadMesh();
	CQuadMeshInstance* CreateInstance();

private:
	GLuint m_IBO;
	Vertex* m_pVertices;
	UINT* m_pIndices;
	UINT m_NumVertices;
	UINT m_NumIndices;
	SGLMethod m_GLMethod;
	Texture m_Texture;
};